﻿using System;
using System.Collections.Concurrent;
using Net.Event;
using Net.Share;
using Net.System;

namespace Net.Server
{
    public partial class ClientPeerBase : ClientPeer
    {
        #region 属性
        /// <summary>
        /// 客户端玩家的标识
        /// </summary>
        public object PlayerId { get; set; } = DBNull.Value;
        /// <summary>
        /// 玩家所在的场景实体
        /// </summary>
        public object Scene { get; set; }
        /// <summary>
        /// 此玩家所在的场景名称
        /// </summary>
        public string SceneName { get; internal set; }
        internal int SceneHash;
        /// <summary>
        /// 是否登录游戏?
        /// </summary>
        public bool IsLogin { get; internal set; }
        /// <summary>
        /// 接收队列
        /// </summary>
        public ConcurrentQueue<ISegment> ReceiveList { get; internal set; } = new();
        #endregion

        protected internal override void NetworkInitialize()
        {
            base.NetworkInitialize();
            RpcAdapter.AddRpc(this);
            OnRpcInvoke ??= DispatchRpc;
        }

        protected override void OnCommand4Handler(IRpcModel model, ISegment segment)
        {
            switch (model.Cmd)
            {
                case NetCmd.LocalHash:
                    if (IsLogin)
                        Call(RpcUnitFactory.Create(cmd: model.Cmd, kernel: model.Kernel, buffer: model.GetBuffer, serialize: SyncSerialize.False, protocol: model.Protocol, token: model.Token));
                    break;
                default:
                    OnReceiveDataHandler(model, segment);
                    break;
            }
        }

        #region 提供简便的重写方法
        /// <summary>
        /// 当玩家登录成功初始化调用
        /// </summary>
        public virtual void OnStart() => NDebug.Log($"[{Name}]登录成功!");

        /// <summary>
        /// 当玩家更新操作
        /// </summary>
        public virtual void OnUpdate() { }

        /// <summary>
        /// 当玩家进入场景 ->场景对象在Scene属性
        /// </summary>
        public virtual void OnEnter() { }

        /// <summary>
        /// 当玩家退出场景 ->场景对象在Scene属性
        /// </summary>
        public virtual void OnExit() { }

        /// <summary>
        /// 当玩家退出登录时调用
        /// </summary>
        public virtual void OnSignOut() { }

        /// <summary>
        /// 当接收到客户端使用<see cref="Net.Client.ClientBase.AddOperation(Operation)"/>方法发送的请求时调用. 如果重写此方法, 
        /// <code>返回false, 则服务器对象类会重新把操作列表加入到场景中, 你可以重写服务器的<see cref="ServerBase{Player, Scene}.OnOperationSync(Player, OperationList)"/>方法让此方法失效</code>
        /// <code>返回true, 服务器不再把数据加入到场景列表, 认为你已经在此处把数据处理了</code>
        /// </summary>
        /// <param name="operList"></param>
        /// <returns></returns>
        public virtual bool OnOperationSync(in OperationList operList) => false;

        /// <summary>
        /// 当属性同步-- 当MysqlBuild生成的类属性在客户端被修改后同步上来会调用此方法
        /// </summary>
        /// <param name="model"></param>
        public virtual void OnPropertySync(IRpcModel model) { }
        #endregion
    }
}